<template>
  <div class="notification-center">
    <!-- 顶部导航 -->
    <van-nav-bar
        title="消息通知"
        left-arrow
        @click-left="handleBack"
        class="custom-nav-bar"
    />

    <!-- 通知统计 -->
    <div class="notification-stats">
      <div
          class="stat-item"
          @click="handleTabChange(null)"
          :class="{ 'active': activeType === null }"
      >
        <span>全部消息</span>
        <span v-if="totalCount > 0" class="count-badge">{{ totalCount }}</span>
      </div>
      <div
          class="stat-item"
          @click="handleTabChange(1)"
          :class="{ 'active': activeType === 1 }"
      >
        <span>系统通知</span>
        <span v-if="emergencyCount > 0" class="count-badge">{{ emergencyCount }}</span>
      </div>
      <div
          class="stat-item"
          @click="handleTabChange(2)"
          :class="{ 'active': activeType === 2 }"
      >
        <span>订单通知</span>
        <span v-if="orderCount > 0" class="count-badge">{{ orderCount }}</span>
      </div>
    </div>

    <!-- 空状态提示 -->
    <div v-if="filteredNotifications.length === 0 && !loading" class="empty-state">
      <van-empty description="暂无通知消息" />
    </div>

    <!-- 通知列表 -->
    <van-list
        v-model:loading="loading"
        :finished="finished"
        finished-text="没有更多了"
        @load="loadMore"
        class="notification-list"
    >
      <van-cell
          v-for="(item, index) in filteredNotifications"
          :key="item.id"
          :class="{ 'unread': item.isRead === 0 }"
          @click="handleNotificationClick(item)"
          class="notification-item"
          hover-class="notification-item-hover"
      >
        <template #icon>
          <div class="notification-icon-wrapper">
            <van-icon
                :name="getNotificationIcon(item.type)"
                :color="getNotificationColor(item.type)"
                size="24"
            />
          </div>
        </template>
        <template #title>
          <div class="notification-title">
            <span>{{ item.title }}</span>
            <span v-if="item.isRead === 0" class="unread-dot"></span>
          </div>
        </template>
        <template #label>
          <div class="notification-content">
            <p class="content-text">{{ item.content }}</p>
            <span class="notification-time">{{ formatTime(item.createdAt) }}</span>
          </div>
        </template>
      </van-cell>
    </van-list>

    <!-- 新消息提示 - 优化动画效果 -->
    <van-toast
        v-if="showNewNotificationToast"
        :message="newNotificationToastMessage"
        position="top"
        duration="3000"
        @close="showNewNotificationToast = false"
        class="new-notification-toast"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import axios from '@/utils/axios';
import { showToast } from 'vant';

// 路由相关
const route = useRoute();
const router = useRouter();

// 状态管理
const data = reactive({
  notifications:[],
  originalRecords:[],
  userId:1,
})
const loading = ref(false);
const finished = ref(false);
const currentPage = ref(1);
const pageSize = ref(10);
const activeType = ref(null);
const unreadCount = ref(0);

// 统计数据
const totalCount = ref(0);
const emergencyCount = ref(0);
const orderCount = ref(0);

// 新消息提示
const showNewNotificationToast = ref(false);
const newNotificationToastMessage = ref('');

// WebSocket相关
let ws = null;
let reconnectTimeout = null;

// 格式化时间
const formatTime = (timeString) => {
  if (!timeString) return '';

  const date = new Date(timeString);
  const now = new Date();
  const diff = now - date;

  // 计算时间差（分钟）
  const minutes = Math.floor(diff / (1000 * 60));

  if (minutes < 60) {
    return `${minutes}分钟前`;
  }

  // 计算时间差（小时）
  const hours = Math.floor(minutes / 60);
  if (hours < 24) {
    return `${hours}小时前`;
  }

  // 计算时间差（天）
  const days = Math.floor(hours / 24);
  if (days < 30) {
    return `${days}天前`;
  }

  // 超过一个月，显示具体日期
  return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
};

// 获取通知图标
const getNotificationIcon = (type) => {
  switch (type) {
    case 1: return 'bell';        // 系统通知
    case 2: return 'calendar';    // 活动通知
    case 3: return 'home-o';      // 物业通知
    case 4: return 'warning';     // 紧急通知
    default: return 'message';
  }
};

// 获取通知颜色
const getNotificationColor = (type) => {
  switch (type) {
    case 1: return '#1989fa';     // 系统通知-蓝色
    case 2: return '#722ed1';     // 活动通知-紫色
    case 3: return '#00b42a';     // 物业通知-绿色
    case 4: return '#f53f3f';     // 紧急通知-红色
    default: return '#86909c';
  }
};

// 过滤通知列表
const filteredNotifications = computed(() => {
  if (activeType.value === null) {
    return data.notifications;
  }
  return data.originalRecords.filter(item => item.type === activeType.value);
});

// 加载通知列表
const loadNotifications = async () => {
  try {
    const response = await axios.post("/api/users/getUserInfo");
    if (response.code == 200){
      console.log("响应的用户数据: ", response.data);
      data.userId = response.data.userId;
    }else {
      console.log("用户数据获取失败");
    }
    const res = await  axios.get(`/api/notification/allNotification/${data.userId}`)
    if (res.code == 200){
      console.log("用户通知数据: ", res.data);
      data.notifications = res.data;
      data.originalRecords = [...res.data];
      totalCount.value = res.data.length;
      calculateNotificationCounts();
    }else {
      console.log("通知响应数据: ", res);
    }
  } catch (error) {
    console.error('加载通知失败:', error);
    showToast('加载通知失败，请稍后重试');
  } finally {
    loading.value = false;
  }
};

// 计算各类通知数量
const calculateNotificationCounts = () => {
  emergencyCount.value = data.notifications.filter(item => item.type === 1).length;
  orderCount.value = data.notifications.filter(item => item.type === 2).length;
};

// 加载更多
const loadMore = () => {
  if (finished.value) return;

  currentPage.value++;
  loadNotifications();
};

// 切换标签
const handleTabChange = (type) => {
  activeType.value = type;
  currentPage.value = 1;
  finished.value = false;
  // 添加切换动画效果
  const listEl = document.querySelector('.notification-list');
  if (listEl) {
    listEl.classList.add('fade-out');
    setTimeout(() => {
      loadNotifications();
      listEl.classList.remove('fade-out');
    }, 200);
  }
};

// 处理通知点击
const handleNotificationClick = async (item) => {
  // 如果是未读通知，标记为已读
  if (item.isRead === 0) {
    try {
      // 更新本地状态
      item.isRead = 1;
      const res = await axios.put("/api/notification/updateReadType", item);
      if (res.code == 200){
        console.log("响应数据: ", res)
      }
      unreadCount.value--;
    } catch (error) {
      console.error('标记已读失败:', error);
      showToast('标记已读失败');
    }
  }

  // 跳转到通知详情页或相关页面
  router.push({
    name: 'notificationDetail',
    query: { nid: item.notificationId, uid:data.userId }
  });
};

// 返回上一页
const handleBack = () => {
  router.push("home");
};

// 初始化WebSocket连接
const initWebSocket = () => {
  // 关闭现有连接
  if (ws) {
    ws.close();
  }

  // 建立新连接
  const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
  const wsUrl = `${wsProtocol}//${window.location.host}/ws/notification?userId=${data.userId}`;

  ws = new WebSocket(wsUrl);

  // 连接成功
  ws.onopen = () => {
    console.log('WebSocket连接成功');

    // 发送心跳检测
    setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({ type: 'heartbeat' }));
      }
    }, 30000);
  };

  // 收到消息
  ws.onmessage = (event) => {
    try {
      const message = JSON.parse(event.data);

      if (message.type === 'notification') {
        // 收到新通知
        const newNotification = message.data;

        // 添加到列表顶部并添加动画
        data.notifications.unshift(newNotification);
        // 触发DOM更新后添加动画类
        setTimeout(() => {
          const firstItem = document.querySelector('.notification-item');
          if (firstItem) {
            firstItem.classList.add('new-notification');
            setTimeout(() => {
              firstItem.classList.remove('new-notification');
            }, 1000);
          }
        }, 0);

        totalCount.value++;

        // 更新计数
        if (newNotification.type === 1) emergencyCount.value++;
        if (newNotification.type === 2) orderCount.value++;

        // 显示提示
        showNewNotificationToast.value = true;
        newNotificationToastMessage.value = `新消息: ${newNotification.title}`;

        // 更新未读数量
        unreadCount.value++;
      }
    } catch (error) {
      console.error('解析WebSocket消息失败:', error);
    }
  };

  // 连接关闭
  ws.onclose = () => {
    console.log('WebSocket连接关闭，尝试重连...');

    // 清除之前的重连计时器
    if (reconnectTimeout) {
      clearTimeout(reconnectTimeout);
    }

    // 3秒后重连
    reconnectTimeout = setTimeout(() => {
      initWebSocket();
    }, 3000);
  };

  // 连接错误
  ws.onerror = (error) => {
    console.error('WebSocket错误:', error);
  };
};

// 获取未读通知数量
const getUnreadCount = async () => {
  try {
    const response = await axios.get('/api/notification/unread/count', {
      params: { userId: data.userId }
    });

    if (response.code === 200) {
      unreadCount.value = response.data;
    }
  } catch (error) {
    console.error('获取未读数量失败:', error);
  }
};

// 页面挂载时初始化
onMounted(() => {
  loadNotifications();
  getUnreadCount();
  initWebSocket();
});

// 页面卸载时清理
onUnmounted(() => {
  if (ws) {
    ws.close();
  }

  if (reconnectTimeout) {
    clearTimeout(reconnectTimeout);
  }
});

// 监听activeType变化，重新加载数据
watch(activeType, () => {
  currentPage.value = 1;
  finished.value = false;
  loadNotifications();
});
</script>

<style scoped>
.notification-center {
  background-color: #f5f7fa;
  min-height: 100vh;
}

/* 导航栏样式优化 */
.custom-nav-bar {
  background: linear-gradient(135deg, #1989fa 0%, #409eff 100%);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.custom-nav-bar /deep/ .van-nav-bar__title {
  color: #fff;
  font-weight: 500;
}

.custom-nav-bar /deep/ .van-icon {
  color: #fff;
}

/* 通知统计标签样式 */
.notification-stats {
  display: flex;
  padding: 15px;
  background-color: #fff;
  border-bottom: 1px solid #eee;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02);
}

.stat-item {
  flex: 1;
  text-align: center;
  padding: 10px 0;
  position: relative;
  cursor: pointer;
  font-size: 15px;
  transition: all 0.3s ease;
  border-bottom: 2px solid transparent;
}

.stat-item.active {
  color: #1989fa;
  border-bottom-color: #1989fa;
  font-weight: 500;
}

.stat-item:active {
  background-color: #f5f7fa;
}

.count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: #f53f3f;
  color: #fff;
  border-radius: 12px;
  padding: 0 6px;
  font-size: 12px;
  margin-left: 5px;
  min-width: 20px;
  height: 20px;
  box-shadow: 0 1px 2px rgba(245, 63, 63, 0.3);
}

/* 通知列表样式 */
.notification-list {
  margin-top: 10px;
  padding-bottom: 20px;
  transition: opacity 0.2s ease;
}

.notification-list.fade-out {
  opacity: 0;
}

.notification-item {
  margin-bottom: 10px;
  background-color: #fff;
  border-radius: 10px;
  margin-left: 10px;
  margin-right: 10px;
  padding: 12px 15px;
  transition: all 0.2s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.notification-item.unread {
  background-color: #f0f7ff;
  border-left: 3px solid #1989fa;
}

.notification-item-hover {
  background-color: #f9f9f9 !important;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

/* 新通知动画 */
.new-notification {
  animation: pulse 1s ease;
}

@keyframes pulse {
  0% {
    background-color: rgba(25, 137, 250, 0.1);
  }
  100% {
    background-color: transparent;
  }
}

/* 通知图标样式 */
.notification-icon-wrapper {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(25, 137, 250, 0.1);
}

/* 通知内容样式 */
.notification-title {
  display: flex;
  align-items: center;
  font-weight: 500;
  font-size: 16px;
  margin-bottom: 4px;
}

.unread-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #f53f3f;
  margin-left: 5px;
  box-shadow: 0 0 0 2px rgba(245, 63, 63, 0.1);
}

.notification-content {
  display: flex;
  flex-direction: column;
}

.content-text {
  color: #86909c;
  font-size: 14px;
  margin-bottom: 5px;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.notification-time {
  color: #c9cdcf;
  font-size: 12px;
  align-self: flex-end;
}

/* 空状态样式 */
.empty-state {
  padding: 50px 20px;
  text-align: center;
}

/* 新消息提示样式 */
.new-notification-toast {
  animation: slideDown 0.3s ease forwards, slideUp 0.3s ease 2.7s forwards;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border-radius: 8px;
  background-color: #fff;
  color: #333;
  border-left: 4px solid #1989fa;
}

@keyframes slideDown {
  from {
    transform: translateY(-100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes slideUp {
  from {
    transform: translateY(0);
    opacity: 1;
  }
  to {
    transform: translateY(-100%);
    opacity: 0;
  }
}
</style>
